/* 
 *	Copyright (C) 2009-2010 miaohua
 *	http://code.google.com/p/lrcshower/
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#pragma once
#include <MMSystem.h>
#include <memory>
#include "LrcShow.h"

class IRender;
// Lrc desktop show class is resposible for rendering lrc text on desktop
class CLrcDesktopShower
{
public:
    // Construnctor & destructor
    CLrcDesktopShower();
    ~CLrcDesktopShower();

    // Change the shower's property functions
    bool ChangeBgClr(COLORREF Clr);
    bool ChangeFocusLineClr(COLORREF UpperClr,COLORREF MidClr, COLORREF LowerClr);
    bool ChangeUnFocusLineClr(COLORREF UpperClr,COLORREF MidClr, COLORREF LowerClr);
	bool ChangeFont(const TCHAR * FontName, int FontSize);
	bool ChangeFont(const LOGFONT* font);
    bool ChangeKaraokeMode(bool Mode);
    bool ChangeShadowMode(bool Mode);
    bool ChangeOutlineMode(bool Mode);
    bool ChangeTopMostMode(bool Mode);
    bool ChangeWinTransMode(bool Mode);
    bool ChangeBgTransparent(BYTE Transparent);
    bool ChangeLrcTransparent(BYTE Transparent);
    bool ChangeMainLrcBuf(const LrcBuf * Buf);
    bool ChangeShowWnd(HWND Win);

	
    // Control functions
    // Start to show the lrc, the default option is to refresh the lrc show window automatically
    bool Start();
    // Reset the shower to be the "start" state(show first line of the lrc)
    bool Reset();
    // Stop to show lrc
    bool Stop();
    // Do scroll job(Start & End is in misecond unit)
    void DoOnTimeScrollJob(long long Now);

private:
	// Help functions
    // Draw one line to screen
	void LineToScreen();
    // Register our lrc show window to system
	ATOM RegisterWinClass(HINSTANCE hInstance);
	// Message hanlder for lrc shwo window
	static LRESULT  CALLBACK OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    // Do clean up jobs
    void Cleanup();
    // Initialize the dekstop shower
    bool DeskShowerInit();
    int  FindRange(long long Start);
    void AdjustLrcLineBuf(int RangeIdx, long long Now);

    // On time to paint    
    static void CALLBACK ScrollLrcTimeOut(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);

    MMRESULT m_ScrollLrcTimer;                 // Synchronal timer for scroll one line lrc show
	ATOM m_WinAtom;                            // Show window's atom handler
	HWND m_ShowWinHandler;                     // Handler of window where the lrc is painted on
    bool m_CreateWinSelf;                      // Wether showing window is created by the class self or passed in 
	RECT m_WinRect;                            // Rectangle of lrc show window
    int  m_FocusLen;                           // Length of paint part lrc
    SIZE m_LrcBoxSize;                         // Containing box size for current line lrc
    tstring  m_FocusLine;                      // Lrc buffer of lrc text
    const LrcBuf * m_LrcBuf;                   // Lrcs buffer of current playing song
    int m_FocusLineIdx;                        // current show line's index in *m_LrcBuf*
    bool m_TopMostMode;                        // Wether show lrc topmost
    bool m_WinTransMode;                       // Wetehr show lrc transparent
    CRITICAL_SECTION m_ParaAccessLock;         // All parameters access & set lock
    std::auto_ptr<IRender> m_TextRender;       // Text render(do real job)
};